/*
REWRITTEN BY XINEF
*/

#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "arcatraz.h"


enum MillhouseSays
{
    SAY_INTRO_1					= 0,
    SAY_INTRO_2					= 1,
    SAY_WATER					= 2,
    SAY_BUFFS					= 3,
    SAY_DRINK					= 4,
    SAY_READY					= 5,
    SAY_KILL					= 6,
    SAY_PYRO					= 7,
    SAY_ICEBLOCK				= 8,
    SAY_LOWHP					= 9,
    SAY_DEATH					= 10,
    SAY_COMPLETE				= 11,
	SAY_INTRO_3					= 12,
	SAY_INTRO_4					= 13,
};

enum MillhouseSpells
{
    SPELL_CONJURE_WATER			= 36879,
    SPELL_ARCANE_INTELLECT		= 36880,
    SPELL_ICE_ARMOR				= 36881,
    SPELL_ARCANE_MISSILES		= 33832,
    SPELL_CONE_OF_COLD			= 12611,
    SPELL_FIRE_BLAST			= 13341,
    SPELL_FIREBALL				= 14034,
    SPELL_FROSTBOLT				= 15497,
    SPELL_PYROBLAST				= 33975,
	SPELL_ICEBLOCK				= 36911,
};

enum MillhouseEvents
{
	EVENT_MILLHOUSE_INTRO1		= 1,
	EVENT_MILLHOUSE_INTRO2		= 2,
	EVENT_MILLHOUSE_INTRO3		= 3,
	EVENT_MILLHOUSE_INTRO4		= 4,
	EVENT_MILLHOUSE_INTRO5		= 5,
	EVENT_MILLHOUSE_INTRO6		= 6,
	EVENT_MILLHOUSE_INTRO7		= 7,
	EVENT_MILLHOUSE_INTRO8		= 8,
	EVENT_MILLHOUSE_INTRO9		= 9,
	EVENT_SEARCH_FIGHT			= 10,
	EVENT_TELEPORT_VISUAL		= 11,

	EVENT_MILL_CHECK_HEALTH		= 20,
	EVENT_MILL_PYROBLAST		= 21,
	EVENT_MILL_BASE_SPELL		= 22,
	EVENT_MILL_ICEBLOCK			= 23
};

class npc_millhouse_manastorm : public CreatureScript
{
    public:
        npc_millhouse_manastorm() : CreatureScript("npc_millhouse_manastorm") { }

        struct npc_millhouse_manastormAI : public ScriptedAI
        {
            npc_millhouse_manastormAI(Creature* creature) : ScriptedAI(creature)
            {
                instance = creature->GetInstanceScript();
            }

            InstanceScript* instance;
			EventMap events;
			EventMap events2;

			void InitializeAI()
			{
				ScriptedAI::InitializeAI();

				me->SetReactState(REACT_PASSIVE);
				me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
				events2.Reset();
				events2.ScheduleEvent(EVENT_TELEPORT_VISUAL, 0);
				events2.ScheduleEvent(EVENT_MILLHOUSE_INTRO1, 3000);
			}

            void Reset()
            {
				events.Reset();
            }

            void AttackStart(Unit* who)
            {
                if (who && me->Attack(who, true))
                    me->GetMotionMaster()->MoveChase(who, 20.0f);
            }

            void KilledUnit(Unit* /*who*/)
            {
                Talk(SAY_KILL);
            }

            void JustDied(Unit* /*killer*/)
            {
                Talk(SAY_DEATH);
            }

			void EnterCombat(Unit*)
			{
				events.ScheduleEvent(EVENT_MILL_CHECK_HEALTH, 1000);
				events.ScheduleEvent(EVENT_MILL_PYROBLAST, 30000);
				events.ScheduleEvent(EVENT_MILL_BASE_SPELL, 2000);
				events.ScheduleEvent(EVENT_MILL_ICEBLOCK, 1000);
			}

            void UpdateAI(uint32 diff)
            {
				events2.Update(diff);
				switch (events2.ExecuteEvent())
				{
					case EVENT_TELEPORT_VISUAL:
						me->CastSpell(me, SPELL_TELEPORT_VISUAL, true);
						break;
					case EVENT_MILLHOUSE_INTRO1:
						Talk(SAY_INTRO_1);
						events2.ScheduleEvent(EVENT_MILLHOUSE_INTRO2, 18000);
						break;
					case EVENT_MILLHOUSE_INTRO2:
						Talk(SAY_INTRO_2);
						events2.ScheduleEvent(EVENT_MILLHOUSE_INTRO3, 8000);
						break;
					case EVENT_MILLHOUSE_INTRO3:
						Talk(SAY_INTRO_3);
						events2.ScheduleEvent(EVENT_MILLHOUSE_INTRO4, 6000);
						break;
					case EVENT_MILLHOUSE_INTRO4:
						Talk(SAY_INTRO_4);
						events2.ScheduleEvent(EVENT_MILLHOUSE_INTRO5, 8000);
						break;
					case EVENT_MILLHOUSE_INTRO5:
						Talk(SAY_WATER);
						me->CastSpell(me, SPELL_CONJURE_WATER, false);
						events2.ScheduleEvent(EVENT_MILLHOUSE_INTRO6, 7000);
						break;
					case EVENT_MILLHOUSE_INTRO6:
						Talk(SAY_BUFFS);
						me->CastSpell(me, SPELL_ICE_ARMOR, false);
						events2.ScheduleEvent(EVENT_MILLHOUSE_INTRO7, 7000);
						break;
					case EVENT_MILLHOUSE_INTRO7:
						Talk(SAY_DRINK);
						me->CastSpell(me, SPELL_ARCANE_INTELLECT, false);
						events2.ScheduleEvent(EVENT_MILLHOUSE_INTRO8, 7000);
						break;
					case EVENT_MILLHOUSE_INTRO8:
						Talk(SAY_READY);
						me->GetMotionMaster()->MovePoint(1, 445.82f, -158.38f, 43.067f);
						events2.ScheduleEvent(EVENT_MILLHOUSE_INTRO9, 5000);
						break;
					case EVENT_MILLHOUSE_INTRO9:
						me->SetFacingTo(M_PI*1.5f);
						me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), M_PI*1.5f);
						me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
						me->SetReactState(REACT_AGGRESSIVE);
						events2.ScheduleEvent(EVENT_SEARCH_FIGHT, 1000);
						break;
					case EVENT_SEARCH_FIGHT:
						if (!me->IsInCombat() && !me->IsInEvadeMode())
							if (Unit* target = me->SelectNearbyTarget(NULL, 30.0f))
								AttackStart(target);
						events2.ScheduleEvent(EVENT_SEARCH_FIGHT, 1000);
						break;

				}

                if (!UpdateVictim())
                    return;

				events.Update(diff);
				if (me->HasUnitState(UNIT_STATE_CASTING))
					return;

				switch (events.ExecuteEvent())
				{
					case EVENT_MILL_CHECK_HEALTH:
						if (HealthBelowPct(20))
						{
							Talk(SAY_LOWHP);
							break;
						}
						events.ScheduleEvent(EVENT_MILL_CHECK_HEALTH, 1000);
						break;
					case EVENT_MILL_PYROBLAST:
						Talk(SAY_PYRO);
						me->CastSpell(me->GetVictim(), SPELL_PYROBLAST, false);
						events.ScheduleEvent(EVENT_MILL_PYROBLAST, 30000);
						break;
					case EVENT_MILL_ICEBLOCK:
						if (me->GetDistance(me->GetVictim()) < 5.0f)
						{
							Talk(SAY_ICEBLOCK);
							me->CastSpell(me, SPELL_ICEBLOCK, true);
							break;
						}
						events.ScheduleEvent(EVENT_MILL_ICEBLOCK, 1000);
						break;
					case EVENT_MILL_BASE_SPELL:
						switch (RAND(SPELL_FIREBALL, SPELL_ARCANE_MISSILES, SPELL_FROSTBOLT))
						{
							case SPELL_FIREBALL:
								me->CastSpell(me->GetVictim(), SPELL_FIREBALL, false);
								events.ScheduleEvent(EVENT_MILL_BASE_SPELL, 4000);
								break;
							case SPELL_ARCANE_MISSILES:
								me->CastSpell(me->GetVictim(), SPELL_ARCANE_MISSILES, false);
								events.ScheduleEvent(EVENT_MILL_BASE_SPELL, 9000);
								break;
							case SPELL_FROSTBOLT:
								me->CastSpell(me->GetVictim(), SPELL_FROSTBOLT, false);
								events.ScheduleEvent(EVENT_MILL_BASE_SPELL, 4000);
								break;
						}
						break;

				}

                DoMeleeAttackIfReady();
            }
        };

        CreatureAI* GetAI(Creature* creature) const
        {
            return new npc_millhouse_manastormAI(creature);
        }
};

enum WardenSays
{
    YELL_INTRO1				= 0,
    YELL_INTRO2				= 1,
    YELL_RELEASE1			= 2,
    YELL_RELEASE2A			= 3,
    YELL_RELEASE2B			= 4,
    YELL_RELEASE3			= 5,
    YELL_RELEASE4			= 6,
    YELL_WELCOME			= 7,

	SAY_HARBINGER_INTRO		= 0,
};

enum WardenUnits
{
    NPC_TRICKSTER		= 20905,
    NPC_PH_HUNTER		= 20906,
    NPC_MILLHOUSE		= 20977,
    NPC_AKKIRIS			= 20908,
    NPC_SULFURON		= 20909,
    NPC_TW_DRAK			= 20910,
    NPC_BL_DRAK			= 20911,
};

enum WardenSpells
{
    SPELL_TARGET_ALPHA  = 36858,
    SPELL_TARGET_BETA   = 36854,
    SPELL_TARGET_DELTA  = 36856,
    SPELL_TARGET_GAMMA  = 36857,
    SPELL_TARGET_OMEGA  = 36852,
    SPELL_BUBBLE_VISUAL = 36849,

	SPELL_MIND_REND		= 36859,
	SPELL_QID10886		= 39564 // Trial of the Naaru: Tenacity
};

enum WardenEvents
{
	EVENT_WARDEN_CHECK_PLAYERS	= 1,
	EVENT_WARDEN_INTRO1			= 2,
	EVENT_WARDEN_INTRO2,
	EVENT_WARDEN_INTRO3,
	EVENT_WARDEN_INTRO4,
	EVENT_WARDEN_INTRO5,
	EVENT_WARDEN_INTRO6,
	EVENT_WARDEN_INTRO7,
	EVENT_WARDEN_INTRO8,
	EVENT_WARDEN_INTRO9,
	EVENT_WARDEN_INTRO10,
	EVENT_WARDEN_INTRO11,
	EVENT_WARDEN_INTRO12,
	EVENT_WARDEN_INTRO13,
	EVENT_WARDEN_INTRO14,
	EVENT_WARDEN_INTRO15,
	EVENT_WARDEN_INTRO16,
	EVENT_WARDEN_INTRO17,
	EVENT_WARDEN_INTRO18,
	EVENT_WARDEN_INTRO19,
	EVENT_WARDEN_INTRO20,
	EVENT_WARDEN_INTRO21,
	EVENT_WARDEN_INTRO22,
	EVENT_WARDEN_INTRO23,
	EVENT_WARDEN_INTRO24,
	EVENT_WARDEN_INTRO25,
	EVENT_WARDEN_INTRO26,
	EVENT_WARDEN_INTRO27,
	EVENT_WARDEN_INTRO28,
	EVENT_WARDEN_INTRO29
};

class npc_warden_mellichar : public CreatureScript
{
    public:
        npc_warden_mellichar() : CreatureScript("npc_warden_mellichar") { }

        struct npc_warden_mellicharAI : public BossAI
        {
            npc_warden_mellicharAI(Creature* creature) : BossAI(creature, DATA_WARDEN_MELLICHAR)
            {
            }

			void JustSummoned(Creature* summon)
			{
				summons.Summon(summon);
			}

			void SummonedCreatureDies(Creature* summon, Unit*)
			{
				if (summon->GetEntry() == NPC_HARBINGER_SKYRISS)
				{
					Unit::Kill(me, me);
					me->setActive(false);
					instance->SetBossState(DATA_WARDEN_MELLICHAR, DONE);
					if (Creature* creature = summons.GetCreatureWithEntry(NPC_MILLHOUSE))
					{
						instance->DoCastSpellOnPlayers(SPELL_QID10886);
						creature->AI()->Talk(SAY_COMPLETE);
						creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
					}
				}
			}

			void MoveInLineOfSight(Unit*) { }
			void AttackStart(Unit*) { }
			void EnterCombat(Unit*) { }

			void JustDied(Unit*)
			{
				me->setActive(false);
			}
 
            void Reset()
            {
				_Reset();
				me->setActive(false);
				me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
				me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
                me->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
				me->CastSpell((Unit*)NULL, SPELL_TARGET_OMEGA, false);
				instance->HandleGameObject(instance->GetData64(DATA_WARDENS_SHIELD), true);
				instance->SetBossState(DATA_WARDEN_MELLICHAR, NOT_STARTED);

            }

			void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask)
			{
				if (attacker && IS_PLAYER_GUID(attacker->GetCharmerOrOwnerOrOwnGUID()) && damage > 0 && !me->isActiveObject())
				{
					me->setActive(true);
					me->InterruptNonMeleeSpells(false);
					me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
					events.ScheduleEvent(EVENT_WARDEN_INTRO1, 1500);
					events.ScheduleEvent(EVENT_WARDEN_CHECK_PLAYERS, 1000);
					instance->SetBossState(DATA_WARDEN_MELLICHAR, IN_PROGRESS);
				}
				damage = 0;
			}

			void SetData(uint32 type, uint32 data)
			{
				if (data == FAIL)
				{
					CreatureAI::EnterEvadeMode();
					return;
				}
				if (data != DONE)
					return;

				switch (type)
				{
					case DATA_WARDEN_1:
						events.ScheduleEvent(EVENT_WARDEN_INTRO8, 2000);
						break;
					case DATA_WARDEN_3:
						events.ScheduleEvent(EVENT_WARDEN_INTRO19, 2000);
						break;
					case DATA_WARDEN_4:
						events.ScheduleEvent(EVENT_WARDEN_INTRO24, 2000);
						break;
				}
			}

			void UpdateAI(uint32 diff)
			{
				events.Update(diff);
				switch (events.ExecuteEvent())
				{
					case EVENT_WARDEN_CHECK_PLAYERS:
						if (!SelectTargetFromPlayerList(100.0f))
						{
							CreatureAI::EnterEvadeMode();
							return;
						}
						events.ScheduleEvent(EVENT_WARDEN_CHECK_PLAYERS, 1000);
						break;
					case EVENT_WARDEN_INTRO1:
						Talk(YELL_INTRO1);
						me->SetFacingTo(M_PI/2.0f);
						me->CastSpell(me, SPELL_BUBBLE_VISUAL, false);
						events.ScheduleEvent(EVENT_WARDEN_INTRO2, 1400);
						break;
					case EVENT_WARDEN_INTRO2:
						instance->HandleGameObject(instance->GetData64(DATA_WARDENS_SHIELD), false);
						events.ScheduleEvent(EVENT_WARDEN_INTRO3, 20000);
						break;
					case EVENT_WARDEN_INTRO3:
                        Talk(YELL_INTRO2);
						events.ScheduleEvent(EVENT_WARDEN_INTRO4, 5000);
						break;
					case EVENT_WARDEN_INTRO4:
						me->SetFacingTo(0.5f);
						me->CastSpell((Unit*)NULL, SPELL_TARGET_ALPHA, false);
						events.ScheduleEvent(EVENT_WARDEN_INTRO5, 2000);
						break;
					case EVENT_WARDEN_INTRO5:
						instance->SetData(DATA_WARDEN_1, IN_PROGRESS);
						events.ScheduleEvent(EVENT_WARDEN_INTRO6, 3000);
						break;
					case EVENT_WARDEN_INTRO6:
						me->SetFacingTo(M_PI*1.5f);
						me->CastSpell((Unit*)NULL, SPELL_TARGET_OMEGA, false);
						events.ScheduleEvent(EVENT_WARDEN_INTRO7, 5000);
						break;
					case EVENT_WARDEN_INTRO7:
                        me->SummonCreature(RAND(NPC_TRICKSTER, NPC_PH_HUNTER), 478.326f, -148.505f, 42.56f, 3.19f, TEMPSUMMON_MANUAL_DESPAWN);
						// Wait for kill
                        break;
					case EVENT_WARDEN_INTRO8:
						Talk(YELL_RELEASE1);
						me->InterruptNonMeleeSpells(false);
						me->SetFacingTo(2.6f);
						events.ScheduleEvent(EVENT_WARDEN_INTRO10, 4000);
						break;
					case EVENT_WARDEN_INTRO10:
						me->CastSpell((Unit*)NULL, SPELL_TARGET_BETA, false);
						events.ScheduleEvent(EVENT_WARDEN_INTRO11, 2000);
						break;
					case EVENT_WARDEN_INTRO11:
						Talk(YELL_RELEASE2A);
						instance->SetData(DATA_WARDEN_2, IN_PROGRESS);
						events.ScheduleEvent(EVENT_WARDEN_INTRO12, 2000);
						break;
					case EVENT_WARDEN_INTRO12:
						me->SetFacingTo(M_PI*1.5f);
						me->CastSpell((Unit*)NULL, SPELL_TARGET_OMEGA, false);
						events.ScheduleEvent(EVENT_WARDEN_INTRO13, 6000);
						break;
					case EVENT_WARDEN_INTRO13:
                        me->SummonCreature(NPC_MILLHOUSE, 413.292f, -148.378f, 42.56f, 6.27f, TEMPSUMMON_MANUAL_DESPAWN);
						events.ScheduleEvent(EVENT_WARDEN_INTRO14, 14000);
                        break;
					case EVENT_WARDEN_INTRO14:
						Talk(YELL_RELEASE2B);
						me->InterruptNonMeleeSpells(false);
						me->SetFacingTo(3.3f);
						events.ScheduleEvent(EVENT_WARDEN_INTRO15, 5000);
						break;
					case EVENT_WARDEN_INTRO15:
						me->CastSpell((Unit*)NULL, SPELL_TARGET_DELTA, false);
						events.ScheduleEvent(EVENT_WARDEN_INTRO16, 2000);
						break;
					case EVENT_WARDEN_INTRO16:
						instance->SetData(DATA_WARDEN_3, IN_PROGRESS);
						events.ScheduleEvent(EVENT_WARDEN_INTRO17, 2000);
						break;
					case EVENT_WARDEN_INTRO17:
						me->SetFacingTo(M_PI*1.5f);
						me->CastSpell((Unit*)NULL, SPELL_TARGET_OMEGA, false);
						events.ScheduleEvent(EVENT_WARDEN_INTRO18, 6000);
						break;
					case EVENT_WARDEN_INTRO18:
                        me->SummonCreature(RAND(NPC_AKKIRIS, NPC_SULFURON), 420.179f, -174.396f, 42.58f, 0.02f, TEMPSUMMON_MANUAL_DESPAWN);
						// Wait for kill
						break;
					case EVENT_WARDEN_INTRO19:
						Talk(YELL_RELEASE3);
						me->InterruptNonMeleeSpells(false);
						me->SetFacingTo(6.05f);
						events.ScheduleEvent(EVENT_WARDEN_INTRO20, 4000);
						break;
					case EVENT_WARDEN_INTRO20:
						me->CastSpell((Unit*)NULL, SPELL_TARGET_GAMMA, false);
						events.ScheduleEvent(EVENT_WARDEN_INTRO21, 2000);
						break;
					case EVENT_WARDEN_INTRO21:
						instance->SetData(DATA_WARDEN_4, IN_PROGRESS);
						events.ScheduleEvent(EVENT_WARDEN_INTRO22, 2000);
						break;
					case EVENT_WARDEN_INTRO22:
						me->SetFacingTo(M_PI*1.5f);
						me->CastSpell((Unit*)NULL, SPELL_TARGET_OMEGA, false);
						events.ScheduleEvent(EVENT_WARDEN_INTRO23, 6000);
						break;
					case EVENT_WARDEN_INTRO23:
						me->SummonCreature(RAND(NPC_TW_DRAK, NPC_BL_DRAK), 471.795f, -174.58f, 42.58f, 3.06f, TEMPSUMMON_MANUAL_DESPAWN);
						// Wait for kill
						break;
					case EVENT_WARDEN_INTRO24:
						instance->SetData(DATA_WARDEN_5, IN_PROGRESS);
						Talk(YELL_RELEASE4);
						me->InterruptNonMeleeSpells(false);
						events.ScheduleEvent(EVENT_WARDEN_INTRO25, 8000);
						break;
					case EVENT_WARDEN_INTRO25:
						if (Creature* cr = me->SummonCreature(NPC_HARBINGER_SKYRISS, 445.763f, -191.639f, 44.64f, 1.60f, TEMPSUMMON_MANUAL_DESPAWN))
						{
							cr->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
							cr->CastSpell(cr, SPELL_TELEPORT_VISUAL, true);
						}
						events.ScheduleEvent(EVENT_WARDEN_INTRO26, 1000);
						break;
					case EVENT_WARDEN_INTRO26:
						if (Creature* creature = summons.GetCreatureWithEntry(NPC_HARBINGER_SKYRISS))
							creature->AI()->Talk(SAY_HARBINGER_INTRO);
						events.ScheduleEvent(EVENT_WARDEN_INTRO27, 23000);
						break;
					case EVENT_WARDEN_INTRO27:
                        Talk(YELL_WELCOME);
						events.ScheduleEvent(EVENT_WARDEN_INTRO28, 5000);
						break;
					case EVENT_WARDEN_INTRO28:
						instance->HandleGameObject(instance->GetData64(DATA_WARDENS_SHIELD), true);
						if (Creature* creature = summons.GetCreatureWithEntry(NPC_HARBINGER_SKYRISS))
							creature->CastSpell((Unit*)NULL, SPELL_MIND_REND, false);
						events.ScheduleEvent(EVENT_WARDEN_INTRO29, 4000);
						break;
					
					case EVENT_WARDEN_INTRO29:
						events.Reset();
						me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
						me->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
						if (Creature* creature = summons.GetCreatureWithEntry(NPC_HARBINGER_SKYRISS))
						{
							creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
							if (Player* player = SelectTargetFromPlayerList(50.0f))
								AttackStart(player);
						}
						break;
				}
			}
        };

        CreatureAI* GetAI(Creature* creature) const
        {
            return new npc_warden_mellicharAI(creature);
        }
};

class spell_arcatraz_soul_steal : public SpellScriptLoader
{
public:
    spell_arcatraz_soul_steal() : SpellScriptLoader("spell_arcatraz_soul_steal") { }

    class spell_arcatraz_soul_steal_AuraScript : public AuraScript
    {
        PrepareAuraScript(spell_arcatraz_soul_steal_AuraScript)
        
		void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
        {
			if (Unit* caster = GetCaster())
				caster->CastSpell(caster, SPELL_SOUL_STEAL, true);
        }

		void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
        {
			if (Unit* caster = GetCaster())
				caster->RemoveAurasDueToSpell(SPELL_SOUL_STEAL);
        }

        void Register()
        {
            OnEffectApply += AuraEffectApplyFn(spell_arcatraz_soul_steal_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
			OnEffectRemove += AuraEffectRemoveFn(spell_arcatraz_soul_steal_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
        }
    };

    AuraScript* GetAuraScript() const
    {
        return new spell_arcatraz_soul_steal_AuraScript();
    }
};

void AddSC_arcatraz()
{
    new npc_millhouse_manastorm();
    new npc_warden_mellichar();

	new spell_arcatraz_soul_steal();
}
